﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel.Composition;
using Microsoft.Practices.ServiceLocation;
using System.Windows.Controls;

namespace Dynamic_UI_Framework
{
    public interface IDesignerItem : IVisual
    { }

    public class DesignerItem : IDesignerItem
    {
        public IVisual CurrentItem
        {
            get { return currentItem; }
            set
            {
                currentItem = value;
                RaiseCurrentItemChanged();
            }
        }
        IVisual currentItem;

        public System.Windows.FrameworkElement Target
        {
            get;
            set;
        }

        public string Name
        {
            get;
            set;
        }

        public IVisual Owner
        {
            get;
            set;
        }

        public void Activate(IVisual v)
        {
            if (Owner != null)
                Owner.Activate(this);
        }

        public List<System.Windows.Controls.MenuItem> GetMenuItem()
        {
            return new List<MenuItem>();
        }

        void RaiseCurrentItemChanged()
        {
            var hander = CurrentItemChanged;
            if (hander != null)
                hander(this, null);
        }

        public event EventHandler CurrentItemChanged;
    }

    [Export("DesignerItem", typeof(IBuilder))]
    public class DesignerItemBuilder : IBuilder
    {
        public UINode GetUINode(IVisual obj)
        {
            DesignerItem di = obj as DesignerItem;
            if (di == null)
                return null;

            UINode node = new UINode();
            node.Target = di;
            node.Name = di.Name;
            node.TypeName = di.GetType().Name;
            node.Properties.Add("target", di.Target.GetType().FullName);
            node.Properties.Add("top", Canvas.GetTop(di.Target));
            node.Properties.Add("left", Canvas.GetLeft(di.Target));

            if (di.CurrentItem != null)
            {
                string key = di.CurrentItem.GetType().Name;
                IBuilder builder = ServiceLocator.Current.GetInstance<IBuilder>(key);
                if (builder == null)
                    throw new Exception("builder == null");

                UINode child = builder.GetUINode(di.CurrentItem);
                child.Owner = node;
                node.Children.Add(child);
            }
            return node;
        }
        public IVisual Build(UINode node)
        {
            string typeFullName = node.Properties.ContainsKey("target") ? node.Properties["target"].ToString() : null;
            if (string.IsNullOrEmpty(typeFullName))
                throw new Exception("string.IsNullOrEmpty(typeFullName)");

            DesignerItemAdapterMapping mapping = ServiceLocator.Current.GetInstance<DesignerItemAdapterMapping>();
            IAdapter adapter = mapping.GetMappingByTypeFullName(typeFullName);
            if (adapter == null)
                throw new Exception("adapter == null");

            DesignerItem region = adapter.DefaultBuild(node.Name) as DesignerItem;
            double top = double.Parse(node.Properties["top"].ToString());
            double left = double.Parse(node.Properties["left"].ToString());
            Canvas.SetTop(region.Target, top);
            Canvas.SetLeft(region.Target, left);
            foreach (var item in node.Children)
            {
                IBuilder builder = ServiceLocator.Current.GetInstance<IBuilder>(item.TypeName);
                IVisual child = builder.Build(item) as IVisual;
                child.Owner = region;
                region.CurrentItem = child;
            }
            return region;
        }
    }
}
